package pl.us.ij.plugins.segmentation.commands.edges;

import ij.ImagePlus;
import ij.process.ByteProcessor;
import ij.process.FloatProcessor;
import pl.us.ij.plugins.segmentation.Trace;
import pl.us.ij.plugins.segmentation.commands.ArrayHelper;
import pl.us.ij.plugins.segmentation.commands.filters.GaussFilterCommand;
import pl.us.ij.plugins.segmentation.infrastructure.Command;
import pl.us.ij.plugins.segmentation.infrastructure.exceptions.BreakCommandException;

/**
 * Created by IntelliJ IDEA.
 * User: Przemek
 * Date: 2010-01-02
 * Time: 23:58:55
 * To change this template use File | Settings | File Templates.
 */
public class DetectEdgesCommand extends Command<DetectEdgesCommandParams> {

    ImagePlus outImp;

    protected void processImage(FloatProcessor fp) throws BreakCommandException {

        float[][] mask = getParams().getMask();

        int width = fp.getWidth();
        int height = fp.getHeight();

        float[] pixels = (float[]) fp.getPixels();

        Trace.logPixels("Mask:", mask, 3, 3);
        Trace.logPixels("Prev:", pixels, 5, 5, width);

        GaussFilterCommand.maskFilter2(mask, width, height, pixels);

        Trace.logPixels("Filtered:", pixels, 5, 5, width);

        normalize(pixels, 0, 1);

        Trace.logPixels("Norm:", pixels, 5, 5, width);

        ArrayHelper.roundMultiply( pixels, 255 );

        Trace.logPixels("Round:", pixels, 5, 5, width);

        byte[] bytePixels = new byte[ pixels.length ];

        for ( int i = 0; i < pixels.length; i++ ) {
            bytePixels[i] = (byte)pixels[i];
        }
        outImp.getProcessor().setPixels(bytePixels);
    }

    public static void normalize(float[] pixels, final float normMin, final float normMax) {
        float min = ArrayHelper.min(pixels);
        float max = ArrayHelper.max(pixels);

        for (int i = 0; i < pixels.length; i++) {
            pixels[i] = (((Math.abs(min - pixels[i]) + normMin) * (normMax - normMin)) / Math.abs(max - min));
        }
    }

    protected void process(FloatProcessor fp) throws BreakCommandException {
        processImage(fp);
    }

    @Override
    protected ImagePlus prepareOutImage(ImagePlus inImage) {

        outImp = new ImagePlus(createOutImageTitle(inImage),
                    new ByteProcessor(inImage.getWidth(), inImage.getHeight()));

        return super.prepareOutImage(inImage);
    }

    @Override
    protected boolean finalizeOutImage(ImagePlus outImp) {

        this.outImp.updateAndDraw();
        this.outImp.show(createOutImageTitle(outImp));

        return false;
    }
}
